package net.tensor.skynet.fragment

import android.content.Context
import android.graphics.Rect
import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.animation.AnimationUtils
import android.widget.AdapterView
import android.widget.ArrayAdapter
import androidx.annotation.RequiresApi
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.gson.Gson
import kotlinx.android.synthetic.main.fragment_grid.*
import kotlinx.android.synthetic.main.fragment_list.*
import kotlinx.android.synthetic.main.fragment_list.recyclerView
import kotlinx.android.synthetic.main.include_toolbar.*
import kotlinx.coroutines.*
import net.tensor.skynet.R
import net.tensor.skynet.adapter.CardAdapter
import net.tensor.skynet.adapter.SkynetAdapter
import net.tensor.skynet.common.user.entity.User
import net.tensor.skynet.entity.DataContainer
import net.tensor.skynet.entity.Model
import net.tensor.skynet.service.UserService
import net.tensor.skynet.utils.BaseUtils
import okhttp3.OkHttpClient
import java.io.InputStream
import java.util.ArrayList
import javax.net.ssl.SSLContext
import javax.net.ssl.X509TrustManager
import kotlin.coroutines.CoroutineContext

class GridDemoFragment : Fragment(R.layout.fragment_grid), CoroutineScope {
    /**
     * job用于控制协程,后面launch{}启动的协程,
     * 返回的job就是这个job对象
     */
    private lateinit var selected: Model
    //job用于控制协程,后面launch{}启动的协程,返回的job就是这个job对象
    private lateinit var job: Job
    private var baseUtils: BaseUtils? = null
    //=======================
    private var trustManager: X509TrustManager? = null
    private var sslContext: SSLContext? = null
    private var okHttpClient: OkHttpClient? = null
    private var gson: Gson? = null
    private var retrofit: UserService? = null
    //=======================

    override fun onDestroy() {
        super.onDestroy()
        //当acitivity结束之后,我们不需要再请求网络了,结束当前协程
        job.cancel()
    }

    //继承CoroutineScope必须初始化coroutineContext变量
    // 这个是标准写法,+其实是plus方法前面表示job,用于控制协程,后面是Dispatchers,指定启动的线程
    override val coroutineContext: CoroutineContext
        get() = job + Dispatchers.Main

    //======================================================================
    private fun initNetwork() {
        job = Job()
        baseUtils = BaseUtils()
        trustManager = baseUtils!!.getTrustManager(this.resources.openRawResource(R.raw.server200))
        sslContext = trustManager?.let { baseUtils!!.getSSLContext(it) }
        okHttpClient =
            sslContext?.let { trustManager?.let { it1 -> baseUtils!!.getOkHttpClient(it1, it) } }
        gson = baseUtils!!.getGson()
        retrofit = okHttpClient?.let {
            baseUtils!!.getRetrofit(
                it,
                "https://192.168.1.200:9999",
                gson ?: Gson()
            )
        }
    }
    //======================================================================
    /**
     * 获取网络数据
     */
    private fun getData(page: Int, pageSize: Int) {
        launch {
            try {
                val map = mutableMapOf<String, Int>()
                map["page"] = page
                map["pageSize"] = pageSize
                val result = withContext(Dispatchers.IO) {
                    retrofit?.queryPage(
                        map
                    )?.execute()
                }
                if (result != null) {
                    if (result.isSuccessful) {
                        DataContainer.pageNum = result.body()?.pageNum ?: 0
                        DataContainer.pageSize = result.body()?.pageSize ?: 0
                        DataContainer.pages = result.body()?.pages ?: 0
                        DataContainer.total = result.body()?.total ?: 0
                        DataContainer.USER_ITEMS = result.body()?.list as ArrayList<User>
                        //启动微调器
                        setupSpinner()
                        //运行布局动画
                        runLayoutAnimation(selected)
                    }
                }
            } catch (e: Exception) { }
        }
    }
    //===============================================================

    @RequiresApi(Build.VERSION_CODES.M)
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        recyclerView.apply {
            layoutManager = GridLayoutManager(context, 4)
            adapter = CardAdapter()
        }
        //启动recyclerView
        setupRecyclerView()
        //启动微调器---调整布局动画
        setupSpinner()
        //运行布局动画
        runLayoutAnimation(selected)
        //获取数据
        //初始化网络
        initNetwork()
        //从网络获取数据
        getData(DataContainer.pageNum, DataContainer.pageSize)
        //=========================================================
        //设置下拉刷新和上拉加载监听
        refreshGradLayout.setOnRefreshListener {
            //...替换数据
            getData(DataContainer.pageNum + 1, DataContainer.pageSize)
//            Snackbar.make(refreshLayout, "下拉加载更多内容", Snackbar.LENGTH_LONG)
//                .setAction("提示", null).show()
            it.finishRefresh()
        }
        refreshGradLayout.setOnLoadMoreListener {
            //...替换数据
//            getData(DataContainer.pageNum + 1, DataContainer.pageSize)
            it.finishLoadMore()
        }
    }

    @RequiresApi(Build.VERSION_CODES.M)
    private fun setupRecyclerView() = recyclerView.apply {
        addItemDecoration(ItemOffsetDecoration(context))
    }

    private fun setupSpinner() = spinner.apply {
        val animations = Model(R.string.animation_scale_random, R.anim.grid_layout_animation_scale_random)
//        val animationNames = getString(animations.nameRes)
        //adapter = ArrayAdapter<Any?>(context, R.layout.row_spinner_item, animationNames)
//        onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
//            override fun onItemSelected(adapterView: AdapterView<*>, view: View?, i: Int, l: Long) {
//                selected = animations.also { runLayoutAnimation(it) }
//            }
//
//            override fun onNothingSelected(adapterView: AdapterView<*>?) = Unit
//        }
        selected = animations
    }

    private fun runLayoutAnimation(model: Model) = recyclerView.apply {
        layoutAnimation = AnimationUtils.loadLayoutAnimation(context, model.resourceId)
        adapter?.notifyDataSetChanged()
        scheduleLayoutAnimation()
    }

    private class ItemOffsetDecoration(
        context: Context
    ) : RecyclerView.ItemDecoration() {
        private val spacing =
            context.resources.getDimensionPixelOffset(R.dimen.default_spacing_small)

        override fun getItemOffsets(
            outRect: Rect,
            view: View,
            parent: RecyclerView,
            state: RecyclerView.State
        ) = outRect.set(spacing, spacing, spacing, spacing)
    }
}
